/***************************************************************
 * Name:      wxCalculatorMain.cpp
 * Purpose:   Code for Application Frame
 * Author:     ()
 * Created:   2023-04-13
 * Copyright:  ()
 * License:
 **************************************************************/

#include "wxCalculatorMain.h"
#include <wx/msgdlg.h>

//(*InternalHeaders(wxCalculatorFrame)
#include <wx/intl.h>
#include <wx/settings.h>
#include <wx/string.h>
//*)

//helper functions
enum wxbuildinfoformat
{
    short_f, long_f
};

wxString wxbuildinfo(wxbuildinfoformat format)
{
    wxString wxbuild(wxVERSION_STRING);

    if (format == long_f )
    {
#if defined(__WXMSW__)
        wxbuild << _T("-Windows");
#elif defined(__UNIX__)
        wxbuild << _T("-Linux");
#endif

#if wxUSE_UNICODE
        wxbuild << _T("-Unicode build");
#else
        wxbuild << _T("-ANSI build");
#endif // wxUSE_UNICODE
    }

    return wxbuild;
}

//(*IdInit(wxCalculatorFrame)
const long wxCalculatorFrame::ID_TEXTDisplay = wxNewId();
const long wxCalculatorFrame::ID_BTNBackSP = wxNewId();
const long wxCalculatorFrame::ID_BTNCE = wxNewId();
const long wxCalculatorFrame::ID_BTNC = wxNewId();
const long wxCalculatorFrame::ID_BTNPM = wxNewId();
const long wxCalculatorFrame::ID_BTN7 = wxNewId();
const long wxCalculatorFrame::ID_BTN8 = wxNewId();
const long wxCalculatorFrame::ID_BTN9 = wxNewId();
const long wxCalculatorFrame::ID_BTNPlus = wxNewId();
const long wxCalculatorFrame::ID_BTN4 = wxNewId();
const long wxCalculatorFrame::ID_BTN5 = wxNewId();
const long wxCalculatorFrame::ID_BTN6 = wxNewId();
const long wxCalculatorFrame::ID_BTNMinus = wxNewId();
const long wxCalculatorFrame::ID_BTN1 = wxNewId();
const long wxCalculatorFrame::ID_BTN2 = wxNewId();
const long wxCalculatorFrame::ID_BTN3 = wxNewId();
const long wxCalculatorFrame::ID_BTNMulti = wxNewId();
const long wxCalculatorFrame::ID_BTN0 = wxNewId();
const long wxCalculatorFrame::ID_BTNDot = wxNewId();
const long wxCalculatorFrame::ID_BTNEqual = wxNewId();
const long wxCalculatorFrame::ID_BTNDiv = wxNewId();
const long wxCalculatorFrame::ID_MENUITEM1 = wxNewId();
const long wxCalculatorFrame::idMenuAbout = wxNewId();
const long wxCalculatorFrame::ID_STATUSBAR1 = wxNewId();
//*)

BEGIN_EVENT_TABLE(wxCalculatorFrame,wxFrame)
    //(*EventTable(wxCalculatorFrame)
    //*)
END_EVENT_TABLE()

wxCalculatorFrame::wxCalculatorFrame(wxWindow* parent,wxWindowID id)
{
    //(*Initialize(wxCalculatorFrame)
    wxBoxSizer* BoxSizer1;
    wxBoxSizer* BoxSizer2;
    wxBoxSizer* BoxSizer3;
    wxBoxSizer* BoxSizer4;
    wxBoxSizer* BoxSizer5;
    wxBoxSizer* BoxSizer6;
    wxMenu* Menu1;
    wxMenu* Menu2;
    wxMenuBar* MenuBar1;
    wxMenuItem* MenuItem1;
    wxMenuItem* MenuItem2;

    Create(parent, wxID_ANY, _("Calculator"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxMAXIMIZE_BOX, _T("wxID_ANY"));
    SetClientSize(wxSize(210,400));
    SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_ACTIVECAPTION));
    BoxSizer1 = new wxBoxSizer(wxVERTICAL);
    txtDisplay = new wxTextCtrl(this, ID_TEXTDisplay, _("0"), wxDefaultPosition, wxSize(196,45), wxTE_RIGHT, wxDefaultValidator, _T("ID_TEXTDisplay"));
    BoxSizer1->Add(txtDisplay, 1, wxALL|wxALIGN_LEFT, 5);
    BoxSizer2 = new wxBoxSizer(wxHORIZONTAL);
    btnBackSp = new wxButton(this, ID_BTNBackSP, _("X"), wxDefaultPosition, wxSize(40,40), 0, wxDefaultValidator, _T("ID_BTNBackSP"));
    BoxSizer2->Add(btnBackSp, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    btnCE = new wxButton(this, ID_BTNCE, _("CE"), wxDefaultPosition, wxSize(40,40), 0, wxDefaultValidator, _T("ID_BTNCE"));
    BoxSizer2->Add(btnCE, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    btnC = new wxButton(this, ID_BTNC, _("C"), wxDefaultPosition, wxSize(40,40), 0, wxDefaultValidator, _T("ID_BTNC"));
    BoxSizer2->Add(btnC, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    btnPM = new wxButton(this, ID_BTNPM, _("-/"), wxDefaultPosition, wxSize(40,40), 0, wxDefaultValidator, _T("ID_BTNPM"));
    BoxSizer2->Add(btnPM, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    BoxSizer1->Add(BoxSizer2, 1, wxALL|wxALIGN_LEFT, 5);
    BoxSizer3 = new wxBoxSizer(wxHORIZONTAL);
    btn7 = new wxButton(this, ID_BTN7, _("7"), wxDefaultPosition, wxSize(40,40), 0, wxDefaultValidator, _T("ID_BTN7"));
    BoxSizer3->Add(btn7, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    btn8 = new wxButton(this, ID_BTN8, _("8"), wxDefaultPosition, wxSize(40,40), 0, wxDefaultValidator, _T("ID_BTN8"));
    BoxSizer3->Add(btn8, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    btn9 = new wxButton(this, ID_BTN9, _("9"), wxDefaultPosition, wxSize(40,40), 0, wxDefaultValidator, _T("ID_BTN9"));
    BoxSizer3->Add(btn9, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    btnPlus = new wxButton(this, ID_BTNPlus, _("+"), wxDefaultPosition, wxSize(40,40), 0, wxDefaultValidator, _T("ID_BTNPlus"));
    BoxSizer3->Add(btnPlus, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    BoxSizer1->Add(BoxSizer3, 1, wxALL|wxALIGN_LEFT, 5);
    BoxSizer4 = new wxBoxSizer(wxHORIZONTAL);
    btn4 = new wxButton(this, ID_BTN4, _("4"), wxDefaultPosition, wxSize(40,40), 0, wxDefaultValidator, _T("ID_BTN4"));
    BoxSizer4->Add(btn4, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    btn5 = new wxButton(this, ID_BTN5, _("5"), wxDefaultPosition, wxSize(40,40), 0, wxDefaultValidator, _T("ID_BTN5"));
    BoxSizer4->Add(btn5, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    btn6 = new wxButton(this, ID_BTN6, _("6"), wxDefaultPosition, wxSize(40,40), 0, wxDefaultValidator, _T("ID_BTN6"));
    BoxSizer4->Add(btn6, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    btnMinus = new wxButton(this, ID_BTNMinus, _("-"), wxDefaultPosition, wxSize(40,40), 0, wxDefaultValidator, _T("ID_BTNMinus"));
    BoxSizer4->Add(btnMinus, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    BoxSizer1->Add(BoxSizer4, 1, wxALL|wxALIGN_LEFT, 5);
    BoxSizer5 = new wxBoxSizer(wxHORIZONTAL);
    btn1 = new wxButton(this, ID_BTN1, _("1"), wxDefaultPosition, wxSize(40,40), 0, wxDefaultValidator, _T("ID_BTN1"));
    BoxSizer5->Add(btn1, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    btn2 = new wxButton(this, ID_BTN2, _("2"), wxDefaultPosition, wxSize(40,40), 0, wxDefaultValidator, _T("ID_BTN2"));
    BoxSizer5->Add(btn2, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    btn3 = new wxButton(this, ID_BTN3, _("3"), wxDefaultPosition, wxSize(40,40), 0, wxDefaultValidator, _T("ID_BTN3"));
    BoxSizer5->Add(btn3, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    btnMulti = new wxButton(this, ID_BTNMulti, _("*"), wxDefaultPosition, wxSize(40,40), 0, wxDefaultValidator, _T("ID_BTNMulti"));
    BoxSizer5->Add(btnMulti, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    BoxSizer1->Add(BoxSizer5, 1, wxALL|wxALIGN_LEFT, 5);
    BoxSizer6 = new wxBoxSizer(wxHORIZONTAL);
    btn0 = new wxButton(this, ID_BTN0, _("0"), wxDefaultPosition, wxSize(40,40), 0, wxDefaultValidator, _T("ID_BTN0"));
    BoxSizer6->Add(btn0, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    btnDot = new wxButton(this, ID_BTNDot, _("."), wxDefaultPosition, wxSize(40,40), 0, wxDefaultValidator, _T("ID_BTNDot"));
    BoxSizer6->Add(btnDot, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    btnEqual = new wxButton(this, ID_BTNEqual, _("="), wxDefaultPosition, wxSize(40,40), 0, wxDefaultValidator, _T("ID_BTNEqual"));
    BoxSizer6->Add(btnEqual, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    btnDiv = new wxButton(this, ID_BTNDiv, _("/"), wxDefaultPosition, wxSize(40,40), 0, wxDefaultValidator, _T("ID_BTNDiv"));
    BoxSizer6->Add(btnDiv, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    BoxSizer1->Add(BoxSizer6, 1, wxALL|wxALIGN_LEFT, 5);
    SetSizer(BoxSizer1);
    MenuBar1 = new wxMenuBar();
    Menu1 = new wxMenu();
    MenuItem1 = new wxMenuItem(Menu1, ID_MENUITEM1, _("Quit\tAlt-F4"), _("Quit the application"), wxITEM_NORMAL);
    Menu1->Append(MenuItem1);
    MenuBar1->Append(Menu1, _("&File"));
    Menu2 = new wxMenu();
    MenuItem2 = new wxMenuItem(Menu2, idMenuAbout, _("About\tF1"), _("Show info about this application"), wxITEM_NORMAL);
    Menu2->Append(MenuItem2);
    MenuBar1->Append(Menu2, _("Help"));
    SetMenuBar(MenuBar1);
    StatusBar1 = new wxStatusBar(this, ID_STATUSBAR1, 0, _T("ID_STATUSBAR1"));
    int __wxStatusBarWidths_1[1] = { -1 };
    int __wxStatusBarStyles_1[1] = { wxSB_NORMAL };
    StatusBar1->SetFieldsCount(1,__wxStatusBarWidths_1);
    StatusBar1->SetStatusStyles(1,__wxStatusBarStyles_1);
    SetStatusBar(StatusBar1);
    SetSizer(BoxSizer1);
    Layout();

    Connect(ID_TEXTDisplay,wxEVT_COMMAND_TEXT_UPDATED,(wxObjectEventFunction)&wxCalculatorFrame::OnTextCtrl1Text);
    Connect(ID_BTNBackSP,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&wxCalculatorFrame::OnbtnBackSpClick);
    Connect(ID_BTNCE,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&wxCalculatorFrame::OnbtnCEClick);
    Connect(ID_BTNC,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&wxCalculatorFrame::OnbtnCClick);
    Connect(ID_BTNPM,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&wxCalculatorFrame::OnbtnPMClick);
    Connect(ID_BTN7,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&wxCalculatorFrame::Onbtn7Click);
    Connect(ID_BTN8,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&wxCalculatorFrame::Onbtn8Click);
    Connect(ID_BTN9,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&wxCalculatorFrame::Onbtn9Click);
    Connect(ID_BTNPlus,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&wxCalculatorFrame::OnbtnPlusClick);
    Connect(ID_BTN4,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&wxCalculatorFrame::Onbtn4Click);
    Connect(ID_BTN5,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&wxCalculatorFrame::Onbtn5Click);
    Connect(ID_BTN6,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&wxCalculatorFrame::Onbtn6Click);
    Connect(ID_BTNMinus,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&wxCalculatorFrame::OnbtnMinusClick);
    Connect(ID_BTN1,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&wxCalculatorFrame::Onbtn1Click);
    Connect(ID_BTN2,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&wxCalculatorFrame::Onbtn2Click);
    Connect(ID_BTN3,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&wxCalculatorFrame::Onbtn3Click);
    Connect(ID_BTNMulti,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&wxCalculatorFrame::OnbtnMultiClick);
    Connect(ID_BTN0,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&wxCalculatorFrame::Onbtn0Click);
    Connect(ID_BTNDot,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&wxCalculatorFrame::OnbtnDotClick);
    Connect(ID_BTNEqual,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&wxCalculatorFrame::OnbtnEqualClick);
    Connect(ID_BTNDiv,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&wxCalculatorFrame::OnbtnDivClick);
    Connect(ID_MENUITEM1,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&wxCalculatorFrame::OnQuit);
    Connect(idMenuAbout,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&wxCalculatorFrame::OnAbout);
    //*)
}

wxCalculatorFrame::~wxCalculatorFrame()
{
    //(*Destroy(wxCalculatorFrame)
    //*)
}

void wxCalculatorFrame::OnQuit(wxCommandEvent& event)
{
    Close();
}

void wxCalculatorFrame::OnAbout(wxCommandEvent& event)
{
    wxString msg = wxbuildinfo(long_f);
    wxMessageBox(msg, _("Welcome to..."));
}

void wxCalculatorFrame::OnTextCtrl1Text(wxCommandEvent& event)
{
}

void wxCalculatorFrame::Onbtn7Click(wxCommandEvent& event)
{
    if(txtDisplay->GetValue() == _("0"))
    {
        txtDisplay->SetValue("7");
    }
    else
    {
        txtDisplay->SetValue(txtDisplay->GetValue()+ _("7"));
    }
}

void wxCalculatorFrame::Onbtn8Click(wxCommandEvent& event)
{
    if(txtDisplay->GetValue() == _("0"))
    {
        txtDisplay->SetValue("8");
    }
    else
    {
        txtDisplay->SetValue(txtDisplay->GetValue()+ _("8"));
    }
}

void wxCalculatorFrame::Onbtn9Click(wxCommandEvent& event)
{
    if(txtDisplay->GetValue() == _("0"))
    {
        txtDisplay->SetValue("9");
    }
    else
    {

        txtDisplay->SetValue(txtDisplay->GetValue()+ _("9"));
    }
}

void wxCalculatorFrame::OnbtnCEClick(wxCommandEvent& event)
{
    txtDisplay->SetValue("0");
}

void wxCalculatorFrame::Onbtn4Click(wxCommandEvent& event)
{
    if(txtDisplay->GetValue() == _("0"))
    {
        txtDisplay->SetValue("4");
    }
    else
    {
        txtDisplay->SetValue(txtDisplay->GetValue()+ _("4"));
    }
}

void wxCalculatorFrame::Onbtn5Click(wxCommandEvent& event)
{
    if(txtDisplay->GetValue() == _("0"))
    {
        txtDisplay->SetValue("5");
    }
    else
    {
        txtDisplay->SetValue(txtDisplay->GetValue()+ _("5"));
    }
}

void wxCalculatorFrame::Onbtn6Click(wxCommandEvent& event)
{
    if(txtDisplay->GetValue() == _("0"))
    {
        txtDisplay->SetValue("6");
    }
    else
    {
        txtDisplay->SetValue(txtDisplay->GetValue()+ _("6"));
    }
}

void wxCalculatorFrame::Onbtn1Click(wxCommandEvent& event)
{
    if(txtDisplay->GetValue() == _("0"))
    {
        txtDisplay->SetValue("1");
    }
    else
    {
        txtDisplay->SetValue(txtDisplay->GetValue()+ _("1"));
    }
}

void wxCalculatorFrame::Onbtn2Click(wxCommandEvent& event)
{
    if(txtDisplay->GetValue() == _("0"))
    {
        txtDisplay->SetValue("2");
    }
    else
    {
        txtDisplay->SetValue(txtDisplay->GetValue()+ _("2"));
    }
}

void wxCalculatorFrame::Onbtn3Click(wxCommandEvent& event)
{
    if(txtDisplay->GetValue() == _("0"))
    {
        txtDisplay->SetValue("3");
    }
    else
    {
        txtDisplay->SetValue(txtDisplay->GetValue()+ _("3"));
    }
}

void wxCalculatorFrame::OnbtnBackSpClick(wxCommandEvent& event)
{
    size_t len = txtDisplay->GetLineLength(0);
    wxString val = txtDisplay->GetValue();

    if(len == 1)
    {
        txtDisplay->SetValue("");
    }
    else
    {
        txtDisplay->SetValue(val.substr(0,len - 1));
    }
}

void wxCalculatorFrame::OnbtnCClick(wxCommandEvent& event)
{
    txtDisplay->SetValue("");
}

void wxCalculatorFrame::OnbtnPMClick(wxCommandEvent& event)
{
    wxString ch = txtDisplay->GetValue();
    double dval;
    ch.ToDouble(&dval);
    dval = -1* dval;
    ch = wxString::Format(_T("%f"), dval);
    txtDisplay->SetValue(ch);
}

void wxCalculatorFrame::OnbtnPlusClick(wxCommandEvent& event)
{
    firstnum = txtDisplay->GetValue();
    operators = 0;
    txtDisplay->SetValue("");
}

void wxCalculatorFrame::OnbtnMinusClick(wxCommandEvent& event)
{
    firstnum = txtDisplay->GetValue();
    operators = 1;
    txtDisplay->SetValue("");
}

void wxCalculatorFrame::OnbtnMultiClick(wxCommandEvent& event)
{
    firstnum = txtDisplay->GetValue();
    operators = 2;
    txtDisplay->SetValue("");
}

void wxCalculatorFrame::OnbtnDivClick(wxCommandEvent& event)
{
    firstnum = txtDisplay->GetValue();
    operators = 3;
    txtDisplay->SetValue("");
}

void wxCalculatorFrame::OnbtnDotClick(wxCommandEvent& event)
{
    wxString ch = txtDisplay->GetValue();

    if(ch.Contains(".") && ch.find_first_of('.',0) != 0)
    {

    }
    else if(!ch.Contains(".") && ch.size() >= 1)
    {
        txtDisplay->SetValue(txtDisplay->GetValue()+ _("."));
    }

}

void wxCalculatorFrame::Onbtn0Click(wxCommandEvent& event)
{
    if(txtDisplay->GetValue() == _("0"))
    {
        txtDisplay->SetValue("0");
    }
    else
    {
        txtDisplay->SetValue(txtDisplay->GetValue()+ _("0"));
    }
}

void wxCalculatorFrame::OnbtnEqualClick(wxCommandEvent& event)
{
    /*
    wxString ch = txtDisplay->GetValue();
    double dval;
    ch.ToDouble(&dval);
    dval = -1* dval;
    ch = wxString::Format(_T("%f"), dval);
    txtDisplay->SetValue(ch);
    */
    secondnum = txtDisplay->GetValue();
    double firval, secval, ansval;

    // wxString to Double
    firstnum.ToDouble(&firval);
    secondnum.ToDouble(&secval);

    switch(operators)
    {
        case 0:
            ansval = firval + secval;
            answer = wxString::Format(_T("%f"), ansval);
            txtDisplay->SetValue(answer);
            break;
        case 1:
            ansval = firval - secval;
            answer = wxString::Format(_T("%f"), ansval);
            txtDisplay->SetValue(answer);
            break;
        case 2:
            ansval = firval * secval;
            answer = wxString::Format(_T("%f"), ansval);
            txtDisplay->SetValue(answer);
            break;
        case 3:
            if(secval == 0.0)
            {
                break;
            }
            ansval = firval / secval;
            answer = wxString::Format(_T("%f"), ansval);
            txtDisplay->SetValue(answer);
            break;
        default:
            break;
    }
}
